Enter the directory of the maca folder on your drive and the name of the tissue you want to analyze.

tissue_of_interest = "Bladder"

Load the requisite packages and some additional helper functions.

library(here)
here() starts at /Users/olgabot/code/tabula-muris
library(useful)
Loading required package: ggplot2
library(Seurat)
Loading required package: cowplot

Attaching package: 'cowplot'
The following object is masked from 'package:ggplot2':

    ggsave
Loading required package: Matrix
Warning: namespace 'Biobase' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'lme4' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'MatrixModels' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'Biobase' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'lme4' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
Warning: namespace 'MatrixModels' is not available and has been replaced
by .GlobalEnv when processing object 'call.'
library(dplyr)
Warning: package 'dplyr' was built under R version 3.4.2

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(Matrix)

save_dir = here('00_data_ingest', 'tissue_robj')
# read the metadata to get the plates we want
plate_metadata_filename = here('00_data_ingest', '00_facs_raw_data', 'metadata_FACS.csv')

plate_metadata <- read.csv(plate_metadata_filename, sep=",", header = TRUE)
colnames(plate_metadata)[1] <- "plate.barcode"
plate_metadata

Load the plate data. “Bladder” is one of the tissues studied

tissue_plates = filter(plate_metadata, tissue == tissue_of_interest)[,c('plate.barcode','tissue','subtissue','mouse.sex')]
tissue_plates

Load the read count data.

#Load the gene names and set the metadata columns by opening the first file
filename = here('00_data_ingest', '00_facs_raw_data', 'FACS', paste0(tissue_of_interest, '-counts.csv'))

raw.data = read.csv(filename, sep=",", row.names=1)
# raw.data = data.frame(row.names = rownames(raw.data))
corner(raw.data)

Make a vector of plate barcodes for each cell

plate.barcodes = lapply(colnames(raw.data), function(x) strsplit(strsplit(x, "_")[[1]][1], '.', fixed=TRUE)[[1]][2])
head(plate.barcodes)
[[1]]
[1] "D041914"

[[2]]
[1] "D041914"

[[3]]
[1] "D041914"

[[4]]
[1] "D041914"

[[5]]
[1] "D041914"

[[6]]
[1] "D041914"
D041914
D041914
D041914
D041914
D041914
D041914

Use only the metadata rows corresponding to Bladder plates. Make a plate barcode dataframe to “expand” the per-plate metadata to be per-cell.

barcode.df = t.data.frame(as.data.frame(plate.barcodes))

rownames(barcode.df) = colnames(raw.data)
colnames(barcode.df) = c('plate.barcode')
head(barcode.df)
                      plate.barcode
A12.D041914.3_8_M.1.1 "D041914"    
B16.D041914.3_8_M.1.1 "D041914"    
C18.D041914.3_8_M.1.1 "D041914"    
D22.D041914.3_8_M.1.1 "D041914"    
F4.D041914.3_8_M.1.1  "D041914"    
C19.D041914.3_8_M.1.1 "D041914"    
D041914

D041914

D041914

D041914

D041914

D041914
rnames = row.names(barcode.df)
meta.data <- merge(barcode.df, plate_metadata, by='plate.barcode', sort = F)
row.names(meta.data) <- rnames
head(meta.data)

Process the raw data and load it into the Seurat object.

# Find ERCC's, compute the percent ERCC, and drop them from the raw data.
erccs <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = TRUE)
percent.ercc <- Matrix::colSums(raw.data[erccs, ])/Matrix::colSums(raw.data)
ercc.index <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = FALSE)
raw.data <- raw.data[-ercc.index,]

# Create the Seurat object with all the data
tiss <- CreateSeuratObject(raw.data = raw.data, project = tissue_of_interest, 
                    min.cells = 5, min.genes = 5)

tiss <- AddMetaData(object = tiss, meta.data)
tiss <- AddMetaData(object = tiss, percent.ercc, col.name = "percent.ercc")
# Change default name for sums of counts from nUMI to nReads
colnames(tiss@meta.data)[colnames(tiss@meta.data) == 'nUMI'] <- 'nReads'

# Create metadata columns for annotations and subannotations
tiss@meta.data[,'annotation'] <- NA
tiss@meta.data[,'subannotation'] <- NA

Calculate percent ribosomal genes.

ribo.genes <- grep(pattern = "^Rp[sl][[:digit:]]", x = rownames(x = tiss@data), value = TRUE)
percent.ribo <- Matrix::colSums(tiss@raw.data[ribo.genes, ])/Matrix::colSums(tiss@raw.data)
tiss <- AddMetaData(object = tiss, metadata = percent.ribo, col.name = "percent.ribo")

A sanity check: genes per cell vs reads per cell.

GenePlot(object = tiss, gene1 = "nReads", gene2 = "nGene", use.raw=T)

Filter out cells with few reads and few genes.

tiss <- FilterCells(object = tiss, subset.names = c("nGene", "nReads"), 
    low.thresholds = c(500, 50000), high.thresholds = c(25000, 2000000))

Normalize the data, then regress out correlation with total reads

tiss <- NormalizeData(object = tiss)
tiss <- ScaleData(object = tiss, vars.to.regress = c("nReads", "percent.ribo","Rn45s"))
[1] "Regressing out nReads"       "Regressing out percent.ribo"
[3] "Regressing out Rn45s"       

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |                                                                 |   1%
  |                                                                       
  |=                                                                |   1%
  |                                                                       
  |=                                                                |   2%
  |                                                                       
  |==                                                               |   2%
  |                                                                       
  |==                                                               |   3%
  |                                                                       
  |==                                                               |   4%
  |                                                                       
  |===                                                              |   4%
  |                                                                       
  |===                                                              |   5%
  |                                                                       
  |====                                                             |   6%
  |                                                                       
  |====                                                             |   7%
  |                                                                       
  |=====                                                            |   7%
  |                                                                       
  |=====                                                            |   8%
  |                                                                       
  |======                                                           |   9%
  |                                                                       
  |======                                                           |  10%
  |                                                                       
  |=======                                                          |  10%
  |                                                                       
  |=======                                                          |  11%
  |                                                                       
  |========                                                         |  12%
  |                                                                       
  |========                                                         |  13%
  |                                                                       
  |=========                                                        |  14%
  |                                                                       
  |==========                                                       |  15%
  |                                                                       
  |==========                                                       |  16%
  |                                                                       
  |===========                                                      |  17%
  |                                                                       
  |============                                                     |  18%
  |                                                                       
  |============                                                     |  19%
  |                                                                       
  |=============                                                    |  20%
  |                                                                       
  |==============                                                   |  21%
  |                                                                       
  |==============                                                   |  22%
  |                                                                       
  |===============                                                  |  23%
  |                                                                       
  |================                                                 |  24%
  |                                                                       
  |================                                                 |  25%
  |                                                                       
  |=================                                                |  26%
  |                                                                       
  |=================                                                |  27%
  |                                                                       
  |==================                                               |  27%
  |                                                                       
  |==================                                               |  28%
  |                                                                       
  |===================                                              |  29%
  |                                                                       
  |===================                                              |  30%
  |                                                                       
  |====================                                             |  30%
  |                                                                       
  |====================                                             |  31%
  |                                                                       
  |=====================                                            |  32%
  |                                                                       
  |=====================                                            |  33%
  |                                                                       
  |======================                                           |  33%
  |                                                                       
  |======================                                           |  34%
  |                                                                       
  |======================                                           |  35%
  |                                                                       
  |=======================                                          |  35%
  |                                                                       
  |=======================                                          |  36%
  |                                                                       
  |========================                                         |  36%
  |                                                                       
  |========================                                         |  37%
  |                                                                       
  |========================                                         |  38%
  |                                                                       
  |=========================                                        |  38%
  |                                                                       
  |=========================                                        |  39%
  |                                                                       
  |==========================                                       |  40%
  |                                                                       
  |==========================                                       |  41%
  |                                                                       
  |===========================                                      |  41%
  |                                                                       
  |===========================                                      |  42%
  |                                                                       
  |============================                                     |  43%
  |                                                                       
  |============================                                     |  44%
  |                                                                       
  |=============================                                    |  44%
  |                                                                       
  |=============================                                    |  45%
  |                                                                       
  |==============================                                   |  46%
  |                                                                       
  |==============================                                   |  47%
  |                                                                       
  |===============================                                  |  48%
  |                                                                       
  |================================                                 |  49%
  |                                                                       
  |================================                                 |  50%
  |                                                                       
  |=================================                                |  51%
  |                                                                       
  |==================================                               |  52%
  |                                                                       
  |===================================                              |  53%
  |                                                                       
  |===================================                              |  54%
  |                                                                       
  |====================================                             |  55%
  |                                                                       
  |====================================                             |  56%
  |                                                                       
  |=====================================                            |  56%
  |                                                                       
  |=====================================                            |  57%
  |                                                                       
  |======================================                           |  58%
  |                                                                       
  |======================================                           |  59%
  |                                                                       
  |=======================================                          |  59%
  |                                                                       
  |=======================================                          |  60%
  |                                                                       
  |========================================                         |  61%
  |                                                                       
  |========================================                         |  62%
  |                                                                       
  |=========================================                        |  62%
  |                                                                       
  |=========================================                        |  63%
  |                                                                       
  |=========================================                        |  64%
  |                                                                       
  |==========================================                       |  64%
  |                                                                       
  |==========================================                       |  65%
  |                                                                       
  |===========================================                      |  65%
  |                                                                       
  |===========================================                      |  66%
  |                                                                       
  |===========================================                      |  67%
  |                                                                       
  |============================================                     |  67%
  |                                                                       
  |============================================                     |  68%
  |                                                                       
  |=============================================                    |  69%
  |                                                                       
  |=============================================                    |  70%
  |                                                                       
  |==============================================                   |  70%
  |                                                                       
  |==============================================                   |  71%
  |                                                                       
  |===============================================                  |  72%
  |                                                                       
  |===============================================                  |  73%
  |                                                                       
  |================================================                 |  73%
  |                                                                       
  |================================================                 |  74%
  |                                                                       
  |=================================================                |  75%
  |                                                                       
  |=================================================                |  76%
  |                                                                       
  |==================================================               |  77%
  |                                                                       
  |===================================================              |  78%
  |                                                                       
  |===================================================              |  79%
  |                                                                       
  |====================================================             |  80%
  |                                                                       
  |=====================================================            |  81%
  |                                                                       
  |=====================================================            |  82%
  |                                                                       
  |======================================================           |  83%
  |                                                                       
  |=======================================================          |  84%
  |                                                                       
  |=======================================================          |  85%
  |                                                                       
  |========================================================         |  86%
  |                                                                       
  |=========================================================        |  87%
  |                                                                       
  |=========================================================        |  88%
  |                                                                       
  |==========================================================       |  89%
  |                                                                       
  |==========================================================       |  90%
  |                                                                       
  |===========================================================      |  90%
  |                                                                       
  |===========================================================      |  91%
  |                                                                       
  |============================================================     |  92%
  |                                                                       
  |============================================================     |  93%
  |                                                                       
  |=============================================================    |  93%
  |                                                                       
  |=============================================================    |  94%
  |                                                                       
  |==============================================================   |  95%
  |                                                                       
  |==============================================================   |  96%
  |                                                                       
  |===============================================================  |  96%
  |                                                                       
  |===============================================================  |  97%
  |                                                                       
  |===============================================================  |  98%
  |                                                                       
  |================================================================ |  98%
  |                                                                       
  |================================================================ |  99%
  |                                                                       
  |=================================================================|  99%
  |                                                                       
  |=================================================================| 100%
[1] "Scaling data matrix"

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |=================================================================| 100%
tiss <- FindVariableGenes(object = tiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.5)

Run Principal Component Analysis.

tiss <- RunPCA(object = tiss, do.print = FALSE)
tiss <- ProjectPCA(object = tiss, do.print = FALSE)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

PCElbowPlot(object = tiss)

Choose the number of principal components to use.

# Set number of principal components. 
n.pcs = 10

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

For the top-level clustering, aim to under-cluster instead of over-cluster. It will be easy to subset groups and further analyze them below.

# Set resolution 
res.used <- 1

tiss <- FindClusters(object = tiss, reduction.type = "pca", dims.use = 1:n.pcs, 
    resolution = res.used, print.output = 0, save.SNN = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
tiss <- RunTSNE(object = tiss, dims.use = 1:n.pcs, seed.use = 10, perplexity=30)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = tiss, do.label = T)

Check expression of genes of interset.

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

VlnPlot(tiss, genes_to_check)

BuildClusterTree(tiss)
[1] "Finished averaging RNA for cluster 0"
[1] "Finished averaging RNA for cluster 1"
[1] "Finished averaging RNA for cluster 2"
[1] "Finished averaging RNA for cluster 3"
[1] "Finished averaging RNA for cluster 4"
[1] "Finished averaging RNA for cluster 5"
[1] "Finished averaging RNA for cluster 6"
[1] "Finished averaging RNA for cluster 7"

An object of class seurat in project Bladder 
 16192 genes across 1287 samples.

How big are the clusters?

table(tiss@ident)

  0   1   2   3   4   5   6   7 
245 191 170 165 165 156  99  96 

Which markers identify a specific cluster?

clust.markers <- FindMarkers(object = tiss, ident.1 = 0, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
DotPlot(tiss, genes.plot = rownames(clust.markers)[1:20], plot.legend = T)

print(x = head(x= clust.markers, n = 10))
               p_val  avg_diff pct.1 pct.2
Gsta4  5.449510e-173 1.2019084 0.976 0.538
Ly6d   9.641989e-148 1.0295347 0.976 0.431
Spint2 4.991041e-125 1.0136621 0.984 0.451
Gsto1  7.278784e-123 1.1488027 0.984 0.616
Mgst3  9.400482e-122 0.9860769 0.976 0.505
Wfdc2  1.468817e-121 0.9021909 0.976 0.391
Krt7   3.690925e-118 1.0821662 0.971 0.384
Krt8   5.563169e-117 1.1631260 0.976 0.461
Igfbp2 2.263129e-116 1.1054429 0.976 0.403
Ldhb   7.139784e-114 0.9933108 0.971 0.603

You can also compute all markers for all clusters at once. This may take some time.

tiss.markers <- FindAllMarkers(object = tiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

Display the top markers you computed above.

#tiss.markers %>% group_by(cluster) %>% top_n(5, avg_diff)
tiss.markers %>% group_by(cluster) %>% top_n(10, avg_diff)

Assigning cell type identity to clusters

At a coarse level, we can use canonical markers to match the unbiased clustering to known cell types:

0: alpha 1: beta 2: beta 3: exocrine 4: duct 5: delta 6: gamma 7: endothelial 8: immune 9: stellate

# stash current cluster IDs
tiss <- StashIdent(object = tiss, save.name = "cluster.ids")

# enumerate current cluster IDs and the labels for them
cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7)
annotation <- c("bladder cell", "bladder cell", "mesenchymal cell", "mesenchymal cell", "mesenchymal cell", "mesenchymal cell", "basal cell of urothelium", "bladder cell")
cell_ontology_id = c("CL:1001319", "CL:1001319", "CL:0008019", "CL:0008019", "CL:0008019", "CL:0008019", "CL:1000486", "CL:1001319")

tiss@meta.data[,'annotation'] <- plyr::mapvalues(x = tiss@meta.data$cluster.ids, from = cluster.ids, to = annotation)
tiss@meta.data[,'cell_ontology_id'] <- plyr::mapvalues(x = tiss@meta.data$cluster.ids, from = cluster.ids, to = cell_ontology_id)

TSNEPlot(object = tiss, do.label = TRUE, pt.size = 0.5, group.by='annotation')

TSNEPlot(object = tiss, do.return = TRUE, group.by = "mouse.sex")

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = tiss, do.return = TRUE, group.by = "plate.barcode")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(tiss@ident), as.character(tiss@meta.data$plate.barcode))
   
    B000610 B002764 B002771 D041914 D042253 MAA000487
  0      87       2      49      65      17        25
  1       2       0       1       1      84       103
  2      58       1      10      97       2         2
  3      41       0      19     100       3         2
  4       1       0       3       1     114        46
  5       2       0       3       2      98        51
  6       0       0       1       0      24        74
  7       6       8      11      50       1        20
# Get markers for a particular cluster
for (i in 0:7) {clustermarkers = filter(tiss.markers, cluster == i)$gene
DotPlot(tiss, genes.plot = clustermarkers[1:20], plot.legend = T)}

# Get subtissue, eg, the endocrine clusters
subtiss <- SubsetData(object = tiss, ident.use = c(2),
  do.center = F, do.scale = F)
subtiss <- SubsetData(object = tiss, ident.use = c(2), do.center = F, do.scale = F, cells.use = )
subtiss <- NormalizeData(object = subtiss)
subtiss <- ScaleData(object = subtiss, vars.to.regress = c("nReads", "percent.ribo","Rn45s"))
[1] "Regressing out nReads"       "Regressing out percent.ribo"
[3] "Regressing out Rn45s"       

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |                                                                 |   1%
  |                                                                       
  |=                                                                |   1%
  |                                                                       
  |=                                                                |   2%
  |                                                                       
  |==                                                               |   2%
  |                                                                       
  |==                                                               |   3%
  |                                                                       
  |==                                                               |   4%
  |                                                                       
  |===                                                              |   4%
  |                                                                       
  |===                                                              |   5%
  |                                                                       
  |====                                                             |   6%
  |                                                                       
  |====                                                             |   7%
  |                                                                       
  |=====                                                            |   7%
  |                                                                       
  |=====                                                            |   8%
  |                                                                       
  |======                                                           |   9%
  |                                                                       
  |======                                                           |  10%
  |                                                                       
  |=======                                                          |  10%
  |                                                                       
  |=======                                                          |  11%
  |                                                                       
  |========                                                         |  12%
  |                                                                       
  |========                                                         |  13%
  |                                                                       
  |=========                                                        |  14%
  |                                                                       
  |==========                                                       |  15%
  |                                                                       
  |==========                                                       |  16%
  |                                                                       
  |===========                                                      |  17%
  |                                                                       
  |============                                                     |  18%
  |                                                                       
  |============                                                     |  19%
  |                                                                       
  |=============                                                    |  20%
  |                                                                       
  |==============                                                   |  21%
  |                                                                       
  |==============                                                   |  22%
  |                                                                       
  |===============                                                  |  23%
  |                                                                       
  |================                                                 |  24%
  |                                                                       
  |================                                                 |  25%
  |                                                                       
  |=================                                                |  26%
  |                                                                       
  |=================                                                |  27%
  |                                                                       
  |==================                                               |  27%
  |                                                                       
  |==================                                               |  28%
  |                                                                       
  |===================                                              |  29%
  |                                                                       
  |===================                                              |  30%
  |                                                                       
  |====================                                             |  30%
  |                                                                       
  |====================                                             |  31%
  |                                                                       
  |=====================                                            |  32%
  |                                                                       
  |=====================                                            |  33%
  |                                                                       
  |======================                                           |  33%
  |                                                                       
  |======================                                           |  34%
  |                                                                       
  |======================                                           |  35%
  |                                                                       
  |=======================                                          |  35%
  |                                                                       
  |=======================                                          |  36%
  |                                                                       
  |========================                                         |  36%
  |                                                                       
  |========================                                         |  37%
  |                                                                       
  |========================                                         |  38%
  |                                                                       
  |=========================                                        |  38%
  |                                                                       
  |=========================                                        |  39%
  |                                                                       
  |==========================                                       |  40%
  |                                                                       
  |==========================                                       |  41%
  |                                                                       
  |===========================                                      |  41%
  |                                                                       
  |===========================                                      |  42%
  |                                                                       
  |============================                                     |  43%
  |                                                                       
  |============================                                     |  44%
  |                                                                       
  |=============================                                    |  44%
  |                                                                       
  |=============================                                    |  45%
  |                                                                       
  |==============================                                   |  46%
  |                                                                       
  |==============================                                   |  47%
  |                                                                       
  |===============================                                  |  48%
  |                                                                       
  |================================                                 |  49%
  |                                                                       
  |================================                                 |  50%
  |                                                                       
  |=================================                                |  51%
  |                                                                       
  |==================================                               |  52%
  |                                                                       
  |===================================                              |  53%
  |                                                                       
  |===================================                              |  54%
  |                                                                       
  |====================================                             |  55%
  |                                                                       
  |====================================                             |  56%
  |                                                                       
  |=====================================                            |  56%
  |                                                                       
  |=====================================                            |  57%
  |                                                                       
  |======================================                           |  58%
  |                                                                       
  |======================================                           |  59%
  |                                                                       
  |=======================================                          |  59%
  |                                                                       
  |=======================================                          |  60%
  |                                                                       
  |========================================                         |  61%
  |                                                                       
  |========================================                         |  62%
  |                                                                       
  |=========================================                        |  62%
  |                                                                       
  |=========================================                        |  63%
  |                                                                       
  |=========================================                        |  64%
  |                                                                       
  |==========================================                       |  64%
  |                                                                       
  |==========================================                       |  65%
  |                                                                       
  |===========================================                      |  65%
  |                                                                       
  |===========================================                      |  66%
  |                                                                       
  |===========================================                      |  67%
  |                                                                       
  |============================================                     |  67%
  |                                                                       
  |============================================                     |  68%
  |                                                                       
  |=============================================                    |  69%
  |                                                                       
  |=============================================                    |  70%
  |                                                                       
  |==============================================                   |  70%
  |                                                                       
  |==============================================                   |  71%
  |                                                                       
  |===============================================                  |  72%
  |                                                                       
  |===============================================                  |  73%
  |                                                                       
  |================================================                 |  73%
  |                                                                       
  |================================================                 |  74%
  |                                                                       
  |=================================================                |  75%
  |                                                                       
  |=================================================                |  76%
  |                                                                       
  |==================================================               |  77%
  |                                                                       
  |===================================================              |  78%
  |                                                                       
  |===================================================              |  79%
  |                                                                       
  |====================================================             |  80%
  |                                                                       
  |=====================================================            |  81%
  |                                                                       
  |=====================================================            |  82%
  |                                                                       
  |======================================================           |  83%
  |                                                                       
  |=======================================================          |  84%
  |                                                                       
  |=======================================================          |  85%
  |                                                                       
  |========================================================         |  86%
  |                                                                       
  |=========================================================        |  87%
  |                                                                       
  |=========================================================        |  88%
  |                                                                       
  |==========================================================       |  89%
  |                                                                       
  |==========================================================       |  90%
  |                                                                       
  |===========================================================      |  90%
  |                                                                       
  |===========================================================      |  91%
  |                                                                       
  |============================================================     |  92%
  |                                                                       
  |============================================================     |  93%
  |                                                                       
  |=============================================================    |  93%
  |                                                                       
  |=============================================================    |  94%
  |                                                                       
  |==============================================================   |  95%
  |                                                                       
  |==============================================================   |  96%
  |                                                                       
  |===============================================================  |  96%
  |                                                                       
  |===============================================================  |  97%
  |                                                                       
  |===============================================================  |  98%
  |                                                                       
  |================================================================ |  98%
  |                                                                       
  |================================================================ |  99%
  |                                                                       
  |=================================================================|  99%
  |                                                                       
  |=================================================================| 100%
[1] "Scaling data matrix"

  |                                                                       
  |                                                                 |   0%
  |                                                                       
  |=================================================================| 100%
subtiss <- FindVariableGenes(object = subtiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.8)

subtiss <- RunPCA(object = subtiss, pcs.compute = 20, weight.by.var = F)
[1] "PC1"
 [1] "Gsn"           "Fbln1"         "Pi16"          "Entpd2"       
 [5] "Lbp"           "Fxyd5"         "Crip2"         "Sparcl1"      
 [9] "Plxdc2"        "Col14a1"       "Arap1"         "Asz1"         
[13] "Cd34"          "Efna5"         "Osr1"          "Fxyd6"        
[17] "Spon2"         "Actg1"         "Gm973"         "Ifi27l2a"     
[21] "Hsd11b1"       "Serpina3n"     "Inmt"          "Fmo1"         
[25] "C4b"           "1810041L15Rik" "Hspa1a"        "Cyp2e1"       
[29] "Ednrb"         "Akap12"       
[1] ""
 [1] "Myl9"          "Ptgs2"         "Plau"          "Myh11"        
 [5] "Gatm"          "Acta2"         "Pde4b"         "Trib1"        
 [9] "Vcam1"         "Nampt"         "Pamr1"         "Prss35"       
[13] "Tagln"         "Procr"         "Mt1"           "Ldha"         
[17] "Ereg"          "Tnfsf9"        "Cish"          "Tnfaip3"      
[21] "Gpnmb"         "Niacr1"        "Ccnd2"         "Cebpd"        
[25] "Rab20"         "Rbp4"          "Sept4"         "1810011O10Rik"
[29] "Nfkbia"        "Iigp1"        
[1] ""
[1] ""
[1] "PC2"
 [1] "Tuba1c"    "Ifrd1"     "Sparcl1"   "Gfpt2"     "Ugdh"     
 [6] "Scara5"    "Mat2a"     "Metrnl"    "Nop58"     "Cish"     
[11] "Chodl"     "Gpr133"    "Pi16"      "Cebpd"     "Nr4a2"    
[16] "Nfkbia"    "Cd55"      "Myc"       "Hk2"       "Errfi1"   
[21] "Tnfrsf12a" "Gadd45b"   "Lbp"       "Uap1"      "Entpd2"   
[26] "Il6"       "Icam1"     "Col14a1"   "Bcl3"      "Tubb6"    
[1] ""
 [1] "Rbp4"     "Nprl2"    "U2af1l4"  "Ier2"     "Avpr1a"   "Tsc22d1" 
 [7] "Zfyve21"  "Tmem204"  "Zfp688"   "Rnf181"   "Cdk9"     "Fbxo31"  
[13] "Bub3"     "Rchy1"    "Tubg1"    "Cdk5rap1" "Crnkl1"   "Qrich1"  
[19] "Wdr8"     "Spin1"    "Glipr2"   "Ddx28"    "Sept4"    "Emilin1" 
[25] "Mum1"     "Ndp"      "Ypel3"    "Trim11"   "Smyd2"    "Rnf114"  
[1] ""
[1] ""
[1] "PC3"
 [1] "Irf2bp1"       "Ide"           "4921517L17Rik" "Ddx28"        
 [5] "Fam53c"        "Nudt13"        "Skiv2l2"       "Fads1"        
 [9] "Usp21"         "Musk"          "H2-Aa"         "Cnot6"        
[13] "Neil1"         "Pknox1"        "E130308A19Rik" "Ddx17"        
[17] "Zfp949"        "Rpap3"         "Dus2l"         "Zfp523"       
[21] "Gss"           "Gabpb1"        "Wdr53"         "Gtf2h2"       
[25] "Irf9"          "Haus4"         "Cenpl"         "Qtrt1"        
[29] "Mxi1"          "Mum1"         
[1] ""
 [1] "Tlk2"     "Ptk7"     "Cdk5rap1" "Qrich1"   "Rilpl1"   "Yars2"   
 [7] "Crnkl1"   "Rfxank"   "Prep"     "Fbxo11"   "Gprasp1"  "Nkd2"    
[13] "Fmo5"     "Prpf3"    "Fbxo31"   "Tmem41a"  "Nprl2"    "Dom3z"   
[19] "Abcg1"    "Pld2"     "Zfp688"   "Pgm5"     "Parp3"    "Eml3"    
[25] "Med4"     "Ecm2"     "Pkdcc"    "Dcxr"     "Cstb"     "Dgcr6"   
[1] ""
[1] ""
[1] "PC4"
 [1] "Gna11"         "Blvrb"         "1810063B07Rik" "A430005L14Rik"
 [5] "Atf3"          "Pdrg1"         "Ier2"          "Tmem222"      
 [9] "9130023H24Rik" "Tor2a"         "Rchy1"         "Bambi"        
[13] "Arl4d"         "Paqr5"         "Bub3"          "Aamp"         
[17] "Ahrr"          "Tsc22d1"       "9430020K01Rik" "Ranbp3"       
[21] "Anapc10"       "Gmpr2"         "Mrpl2"         "Ypel3"        
[25] "Bmp3"          "Sumf2"         "Txndc16"       "Atpaf2"       
[29] "Rtkn"          "Mlycd"        
[1] ""
 [1] "Arhgap21"      "Nacc2"         "Cdk5rap1"      "Rfxank"       
 [5] "Crnkl1"        "Ptk7"          "Arfgap2"       "Mcmbp"        
 [9] "Rilpl1"        "Rbmx"          "Prep"          "Ppil4"        
[13] "Pcdhgc3"       "Tlk2"          "Map2k3"        "Cnot6"        
[17] "Nit2"          "Neil1"         "Pcsk5"         "Fmo5"         
[21] "Gprasp1"       "H2-Aa"         "Eml3"          "Fads1"        
[25] "Prpf3"         "4921517L17Rik" "Lman2l"        "Hyal2"        
[29] "Nkd2"          "Qrich1"       
[1] ""
[1] ""
[1] "PC5"
 [1] "Calcrl"        "Dnaja1"        "Ppp1r15a"      "Spin1"        
 [5] "Plat"          "Ece1"          "Gsn"           "Rbp4"         
 [9] "Lmna"          "Sdc4"          "Ptn"           "Smad3"        
[13] "Tspan8"        "Cd14"          "Cd1d1"         "Gadd45b"      
[17] "Tcp11l2"       "Naaa"          "Cxcl12"        "Hspa1a"       
[21] "2010011I20Rik" "Uap1"          "Nfkbia"        "Fmo2"         
[25] "Fbln5"         "Mpv17"         "Arl8b"         "Rabl3"        
[29] "Hbegf"         "2010002N04Rik"
[1] ""
 [1] "Itih5"         "Myl9"          "Npy1r"         "Mfap5"        
 [5] "Acta2"         "Igfbp4"        "Nhsl2"         "Actg2"        
 [9] "Prss35"        "Nsg1"          "Glul"          "Col8a1"       
[13] "Mtch2"         "Sqrdl"         "Serpina3n"     "Mgp"          
[17] "Mcm7"          "Lifr"          "Tspan4"        "Zfp259"       
[21] "Top2a"         "Slc9a3r2"      "Arhgdib"       "Rpap3"        
[25] "Fnta"          "Pomt2"         "8430410A17Rik" "Mki67ip"      
[29] "Acy1"          "Ddx39"        
[1] ""
[1] ""
subtiss <- ProjectPCA(object = subtiss, do.print = FALSE)
# If this fails for your subset, it may be that cells.use is more cells than you have left! Try reducing it.
PCHeatmap(object = subtiss, pc.use = 1:3, cells.use = 250, do.balanced = TRUE, label.columns = FALSE, num.genes = 12)

PCElbowPlot(object = subtiss)

# Set number of principal components. 
sub.n.pcs = 5
# Set resolution 
sub.res.used <- 1

subtiss <- FindClusters(object = subtiss, reduction.type = "pca", dims.use = 1:sub.n.pcs, 
    resolution = sub.res.used, ,print.output = 0, save.SNN = TRUE)
# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
subtiss <- RunTSNE(object = subtiss, dims.use = 1:sub.n.pcs, seed.use = 10, perplexity=20)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = subtiss, do.label = T)

TSNEPlot(object = subtiss, do.return = TRUE, group.by = "mouse.sex")

genes_to_check = c('Hhip','Dcn', 'Gli1','Gli2', 'Smo','Col1a1','Col8a1')
#genes_to_check = c('Alb', 'Cyp2f2', 'Cyp2e1', 'Hamp')

FeaturePlot(subtiss, genes_to_check, pt.size = 1, nCol = 3)

VlnPlot(subtiss, genes_to_check)

clust.markers <- FindMarkers(object = subtiss, ident.1 = 0, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
clust.markers 
clust.markersuro <- FindMarkers(object = subtiss, ident.1 = 0, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
clust.markersuro
GenePlot(subtiss, 'Upk3a', 'Krt14', use.raw = T)
Warning in cor(x = data.plot$x, y = data.plot$y): the standard deviation is
zero

BuildClusterTree(subtiss)
[1] "Finished averaging RNA for cluster 0"
[1] "Finished averaging RNA for cluster 1"
[1] "Finished averaging RNA for cluster 2"
[1] "Finished averaging RNA for cluster 3"

An object of class seurat in project Bladder 
 16192 genes across 170 samples.
VlnPlot(subtiss, genes_to_check)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

Check expression of genes of interset.

genes_to_check = c('Btg2','Sgk1','Jun','Srsf2')

FeaturePlot(subtiss, genes_to_check, pt.size = 1)

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

# To change the y-axis to show raw counts, add use.raw = T.
DotPlot(subtiss, genes_to_check, plot.legend = T)

How big are the clusters?

table(subtiss@ident)

 0  1  2  3 
57 48 43 22 

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = subtiss, do.return = TRUE, group.by = "plate.barcode")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(subtiss@ident), as.character(subtiss@meta.data$plate.barcode))
   
    B000610 B002764 B002771 D041914 D042253 MAA000487
  0      15       0       5      35       1         1
  1       3       1       0      42       1         1
  2      38       0       5       0       0         0
  3       2       0       0      20       0         0

Save the Robject for later

When you save the annotated tissue, please give it a name.

filename = here('00_data_ingest', '04_tissue_robj_generated', 
          paste0(tissue_of_interest, "_seurat_tiss.Robj"))
print(filename)
[1] "/Users/olgabot/code/tabula-muris/00_data_ingest/04_tissue_robj_generated/Bladder_seurat_tiss.Robj"
save(tiss, file=filename)
# To reload a saved object
# filename = here('00_data_ingest', '04_tissue_robj_generated', 
#                      paste0(tissue_of_interest, "_seurat_tiss.Robj"))
# load(file=filename)

Export the final metadata

So that Biohub can easily combine all your annotations, please export them as a simple csv.

head(tiss@meta.data)
filename = here('00_data_ingest', '03_tissue_annotation_csv', 
          paste0(tissue_of_interest, "_annotation.csv"))
write.csv(tiss@meta.data[,c('plate.barcode','annotation','cell_ontology_id')], file=filename)
LS0tCnRpdGxlOiAiQmxhZGRlciBGQUNTIE5vdGVib29rIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpFbnRlciB0aGUgZGlyZWN0b3J5IG9mIHRoZSBtYWNhIGZvbGRlciBvbiB5b3VyIGRyaXZlIGFuZCB0aGUgbmFtZSBvZiB0aGUgdGlzc3VlIHlvdSB3YW50IHRvIGFuYWx5emUuCgpgYGB7cn0KdGlzc3VlX29mX2ludGVyZXN0ID0gIkJsYWRkZXIiCmBgYAoKTG9hZCB0aGUgcmVxdWlzaXRlIHBhY2thZ2VzIGFuZCBzb21lIGFkZGl0aW9uYWwgaGVscGVyIGZ1bmN0aW9ucy4KCmBgYHtyfQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkodXNlZnVsKQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShkcGx5cikKbGlicmFyeShNYXRyaXgpCgpzYXZlX2RpciA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJ3Rpc3N1ZV9yb2JqJykKYGBgCgoKCmBgYHtyfQojIHJlYWQgdGhlIG1ldGFkYXRhIHRvIGdldCB0aGUgcGxhdGVzIHdlIHdhbnQKcGxhdGVfbWV0YWRhdGFfZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICdmYWNzX3Jhd19kYXRhJywgJ21ldGFkYXRhX0ZBQ1MuY3N2JykKCnBsYXRlX21ldGFkYXRhIDwtIHJlYWQuY3N2KHBsYXRlX21ldGFkYXRhX2ZpbGVuYW1lLCBzZXA9IiwiLCBoZWFkZXIgPSBUUlVFKQpjb2xuYW1lcyhwbGF0ZV9tZXRhZGF0YSlbMV0gPC0gInBsYXRlLmJhcmNvZGUiCnBsYXRlX21ldGFkYXRhCmBgYAoKTG9hZCB0aGUgcGxhdGUgZGF0YS4gIkJsYWRkZXIiIGlzIG9uZSBvZiB0aGUgdGlzc3VlcyBzdHVkaWVkCgpgYGB7cn0KdGlzc3VlX3BsYXRlcyA9IGZpbHRlcihwbGF0ZV9tZXRhZGF0YSwgdGlzc3VlID09IHRpc3N1ZV9vZl9pbnRlcmVzdClbLGMoJ3BsYXRlLmJhcmNvZGUnLCd0aXNzdWUnLCdzdWJ0aXNzdWUnLCdtb3VzZS5zZXgnKV0KdGlzc3VlX3BsYXRlcwpgYGAKCkxvYWQgdGhlIHJlYWQgY291bnQgZGF0YS4KYGBge3J9CiNMb2FkIHRoZSBnZW5lIG5hbWVzIGFuZCBzZXQgdGhlIG1ldGFkYXRhIGNvbHVtbnMgYnkgb3BlbmluZyB0aGUgZmlyc3QgZmlsZQpmaWxlbmFtZSA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJ2ZhY3NfcmF3X2RhdGEnLCAnRkFDUycsIHBhc3RlMCh0aXNzdWVfb2ZfaW50ZXJlc3QsICctY291bnRzLmNzdicpKQoKcmF3LmRhdGEgPSByZWFkLmNzdihmaWxlbmFtZSwgc2VwPSIsIiwgcm93Lm5hbWVzPTEpCiMgcmF3LmRhdGEgPSBkYXRhLmZyYW1lKHJvdy5uYW1lcyA9IHJvd25hbWVzKHJhdy5kYXRhKSkKY29ybmVyKHJhdy5kYXRhKQpgYGAKTWFrZSBhIHZlY3RvciBvZiBwbGF0ZSBiYXJjb2RlcyBmb3IgZWFjaCBjZWxsCgpgYGB7cn0KcGxhdGUuYmFyY29kZXMgPSBsYXBwbHkoY29sbmFtZXMocmF3LmRhdGEpLCBmdW5jdGlvbih4KSBzdHJzcGxpdChzdHJzcGxpdCh4LCAiXyIpW1sxXV1bMV0sICcuJywgZml4ZWQ9VFJVRSlbWzFdXVsyXSkKaGVhZChwbGF0ZS5iYXJjb2RlcykKYGBgCgpVc2Ugb25seSB0aGUgbWV0YWRhdGEgcm93cyBjb3JyZXNwb25kaW5nIHRvIEJsYWRkZXIgcGxhdGVzLiBNYWtlIGEgcGxhdGUgYmFyY29kZSBkYXRhZnJhbWUgdG8gImV4cGFuZCIgdGhlIHBlci1wbGF0ZSBtZXRhZGF0YSB0byBiZSBwZXItY2VsbC4KYGBge3J9CmJhcmNvZGUuZGYgPSB0LmRhdGEuZnJhbWUoYXMuZGF0YS5mcmFtZShwbGF0ZS5iYXJjb2RlcykpCgpyb3duYW1lcyhiYXJjb2RlLmRmKSA9IGNvbG5hbWVzKHJhdy5kYXRhKQpjb2xuYW1lcyhiYXJjb2RlLmRmKSA9IGMoJ3BsYXRlLmJhcmNvZGUnKQpoZWFkKGJhcmNvZGUuZGYpCgpybmFtZXMgPSByb3cubmFtZXMoYmFyY29kZS5kZikKbWV0YS5kYXRhIDwtIG1lcmdlKGJhcmNvZGUuZGYsIHBsYXRlX21ldGFkYXRhLCBieT0ncGxhdGUuYmFyY29kZScsIHNvcnQgPSBGKQpyb3cubmFtZXMobWV0YS5kYXRhKSA8LSBybmFtZXMKaGVhZChtZXRhLmRhdGEpCmBgYAoKUHJvY2VzcyB0aGUgcmF3IGRhdGEgYW5kIGxvYWQgaXQgaW50byB0aGUgU2V1cmF0IG9iamVjdC4KCmBgYHtyfQojIEZpbmQgRVJDQydzLCBjb21wdXRlIHRoZSBwZXJjZW50IEVSQ0MsIGFuZCBkcm9wIHRoZW0gZnJvbSB0aGUgcmF3IGRhdGEuCmVyY2NzIDwtIGdyZXAocGF0dGVybiA9ICJeRVJDQy0iLCB4ID0gcm93bmFtZXMoeCA9IHJhdy5kYXRhKSwgdmFsdWUgPSBUUlVFKQpwZXJjZW50LmVyY2MgPC0gTWF0cml4Ojpjb2xTdW1zKHJhdy5kYXRhW2VyY2NzLCBdKS9NYXRyaXg6OmNvbFN1bXMocmF3LmRhdGEpCmVyY2MuaW5kZXggPC0gZ3JlcChwYXR0ZXJuID0gIl5FUkNDLSIsIHggPSByb3duYW1lcyh4ID0gcmF3LmRhdGEpLCB2YWx1ZSA9IEZBTFNFKQpyYXcuZGF0YSA8LSByYXcuZGF0YVstZXJjYy5pbmRleCxdCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCB3aXRoIGFsbCB0aGUgZGF0YQp0aXNzIDwtIENyZWF0ZVNldXJhdE9iamVjdChyYXcuZGF0YSA9IHJhdy5kYXRhLCBwcm9qZWN0ID0gdGlzc3VlX29mX2ludGVyZXN0LCAKICAgICAgICAgICAgICAgICAgICBtaW4uY2VsbHMgPSA1LCBtaW4uZ2VuZXMgPSA1KQoKdGlzcyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSB0aXNzLCBtZXRhLmRhdGEpCnRpc3MgPC0gQWRkTWV0YURhdGEob2JqZWN0ID0gdGlzcywgcGVyY2VudC5lcmNjLCBjb2wubmFtZSA9ICJwZXJjZW50LmVyY2MiKQojIENoYW5nZSBkZWZhdWx0IG5hbWUgZm9yIHN1bXMgb2YgY291bnRzIGZyb20gblVNSSB0byBuUmVhZHMKY29sbmFtZXModGlzc0BtZXRhLmRhdGEpW2NvbG5hbWVzKHRpc3NAbWV0YS5kYXRhKSA9PSAnblVNSSddIDwtICduUmVhZHMnCgojIENyZWF0ZSBtZXRhZGF0YSBjb2x1bW5zIGZvciBhbm5vdGF0aW9ucyBhbmQgc3ViYW5ub3RhdGlvbnMKdGlzc0BtZXRhLmRhdGFbLCdhbm5vdGF0aW9uJ10gPC0gTkEKdGlzc0BtZXRhLmRhdGFbLCdzdWJhbm5vdGF0aW9uJ10gPC0gTkEKYGBgCgoKQ2FsY3VsYXRlIHBlcmNlbnQgcmlib3NvbWFsIGdlbmVzLgoKYGBge3J9CnJpYm8uZ2VuZXMgPC0gZ3JlcChwYXR0ZXJuID0gIl5ScFtzbF1bWzpkaWdpdDpdXSIsIHggPSByb3duYW1lcyh4ID0gdGlzc0BkYXRhKSwgdmFsdWUgPSBUUlVFKQpwZXJjZW50LnJpYm8gPC0gTWF0cml4Ojpjb2xTdW1zKHRpc3NAcmF3LmRhdGFbcmliby5nZW5lcywgXSkvTWF0cml4Ojpjb2xTdW1zKHRpc3NAcmF3LmRhdGEpCnRpc3MgPC0gQWRkTWV0YURhdGEob2JqZWN0ID0gdGlzcywgbWV0YWRhdGEgPSBwZXJjZW50LnJpYm8sIGNvbC5uYW1lID0gInBlcmNlbnQucmlibyIpCmBgYAoKQSBzYW5pdHkgY2hlY2s6IGdlbmVzIHBlciBjZWxsIHZzIHJlYWRzIHBlciBjZWxsLgoKYGBge3J9CkdlbmVQbG90KG9iamVjdCA9IHRpc3MsIGdlbmUxID0gIm5SZWFkcyIsIGdlbmUyID0gIm5HZW5lIiwgdXNlLnJhdz1UKQpgYGAKCkZpbHRlciBvdXQgY2VsbHMgd2l0aCBmZXcgcmVhZHMgYW5kIGZldyBnZW5lcy4KCmBgYHtyfQp0aXNzIDwtIEZpbHRlckNlbGxzKG9iamVjdCA9IHRpc3MsIHN1YnNldC5uYW1lcyA9IGMoIm5HZW5lIiwgIm5SZWFkcyIpLCAKICAgIGxvdy50aHJlc2hvbGRzID0gYyg1MDAsIDUwMDAwKSwgaGlnaC50aHJlc2hvbGRzID0gYygyNTAwMCwgMjAwMDAwMCkpCmBgYAoKCk5vcm1hbGl6ZSB0aGUgZGF0YSwgdGhlbiByZWdyZXNzIG91dCBjb3JyZWxhdGlvbiB3aXRoIHRvdGFsIHJlYWRzCmBgYHtyfQp0aXNzIDwtIE5vcm1hbGl6ZURhdGEob2JqZWN0ID0gdGlzcykKdGlzcyA8LSBTY2FsZURhdGEob2JqZWN0ID0gdGlzcywgdmFycy50by5yZWdyZXNzID0gYygiblJlYWRzIiwgInBlcmNlbnQucmlibyIsIlJuNDVzIikpCnRpc3MgPC0gRmluZFZhcmlhYmxlR2VuZXMob2JqZWN0ID0gdGlzcywgZG8ucGxvdCA9IFRSVUUsIHguaGlnaC5jdXRvZmYgPSBJbmYsIHkuY3V0b2ZmID0gMC41KQpgYGAKCgpSdW4gUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcy4KYGBge3J9CnRpc3MgPC0gUnVuUENBKG9iamVjdCA9IHRpc3MsIGRvLnByaW50ID0gRkFMU0UpCnRpc3MgPC0gUHJvamVjdFBDQShvYmplY3QgPSB0aXNzLCBkby5wcmludCA9IEZBTFNFKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQpQQ0hlYXRtYXAob2JqZWN0ID0gdGlzcywgcGMudXNlID0gMTozLCBjZWxscy51c2UgPSA1MDAsIGRvLmJhbGFuY2VkID0gVFJVRSwgbGFiZWwuY29sdW1ucyA9IEZBTFNFLCBudW0uZ2VuZXMgPSA4KQpgYGAKCkxhdGVyIG9uIChpbiBGaW5kQ2x1c3RlcnMgYW5kIFRTTkUpIHlvdSB3aWxsIHBpY2sgYSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGtlZXBpbmcgdGhlIG1ham9yIGRpcmVjdGlvbnMgb2YgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGFuZCwgaWRlYWxseSwgc3VwcmVzc2luZyBub2lzZS4gVGhlcmUgaXMgbm8gY29ycmVjdCBhbnN3ZXIgdG8gdGhlIG51bWJlciB0byB1c2UsIGJ1dCBhIGRlY2VudCBydWxlIG9mIHRodW1iIGlzIHRvIGdvIHVudGlsIHRoZSBwbG90IHBsYXRlYXVzLgoKYGBge3J9ClBDRWxib3dQbG90KG9iamVjdCA9IHRpc3MpCmBgYAoKQ2hvb3NlIHRoZSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLgpgYGB7cn0KIyBTZXQgbnVtYmVyIG9mIHByaW5jaXBhbCBjb21wb25lbnRzLiAKbi5wY3MgPSAxMApgYGAKCgpUaGUgY2x1c3RlcmluZyBpcyBwZXJmb3JtZWQgYmFzZWQgb24gYSBuZWFyZXN0IG5laWdoYm9ycyBncmFwaC4gQ2VsbHMgdGhhdCBoYXZlIHNpbWlsYXIgZXhwcmVzc2lvbiB3aWxsIGJlIGpvaW5lZCB0b2dldGhlci4gVGhlIExvdXZhaW4gYWxnb3JpdGhtIGxvb2tzIGZvciBncm91cHMgb2YgY2VsbHMgd2l0aCBoaWdoIG1vZHVsYXJpdHktLW1vcmUgY29ubmVjdGlvbnMgd2l0aGluIHRoZSBncm91cCB0aGFuIGJldHdlZW4gZ3JvdXBzLiBUaGUgcmVzb2x1dGlvbiBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB0aGUgc2NhbGUuLi5oaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgbW9yZSBjbHVzdGVycywgbG93ZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgZmV3ZXIuCgpGb3IgdGhlIHRvcC1sZXZlbCBjbHVzdGVyaW5nLCBhaW0gdG8gdW5kZXItY2x1c3RlciBpbnN0ZWFkIG9mIG92ZXItY2x1c3Rlci4gSXQgd2lsbCBiZSBlYXN5IHRvIHN1YnNldCBncm91cHMgYW5kIGZ1cnRoZXIgYW5hbHl6ZSB0aGVtIGJlbG93LgoKYGBge3J9CiMgU2V0IHJlc29sdXRpb24gCnJlcy51c2VkIDwtIDEKCnRpc3MgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IHRpc3MsIHJlZHVjdGlvbi50eXBlID0gInBjYSIsIGRpbXMudXNlID0gMTpuLnBjcywgCiAgICByZXNvbHV0aW9uID0gcmVzLnVzZWQsIHByaW50Lm91dHB1dCA9IDAsIHNhdmUuU05OID0gVFJVRSkKYGBgCgpUbyB2aXN1YWxpemUgCmBgYHtyfQojIElmIGNlbGxzIGFyZSB0b28gc3ByZWFkIG91dCwgeW91IGNhbiByYWlzZSB0aGUgcGVycGxleGl0eS4gSWYgeW91IGhhdmUgZmV3IGNlbGxzLCB0cnkgYSBsb3dlciBwZXJwbGV4aXR5IChidXQgbmV2ZXIgbGVzcyB0aGFuIDEwKS4KdGlzcyA8LSBSdW5UU05FKG9iamVjdCA9IHRpc3MsIGRpbXMudXNlID0gMTpuLnBjcywgc2VlZC51c2UgPSAxMCwgcGVycGxleGl0eT0zMCkKYGBgCgpgYGB7cn0KIyBub3RlIHRoYXQgeW91IGNhbiBzZXQgZG8ubGFiZWw9VCB0byBoZWxwIGxhYmVsIGluZGl2aWR1YWwgY2x1c3RlcnMKVFNORVBsb3Qob2JqZWN0ID0gdGlzcywgZG8ubGFiZWwgPSBUKQpgYGAKCgpDaGVjayBleHByZXNzaW9uIG9mIGdlbmVzIG9mIGludGVyc2V0LgoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD04fQpnZW5lc190b19jaGVjayA9IGMoJ0VwY2FtJywnVXBrMWInLCAnVXBrM2EnLCdHcmhsMycsICdLcnQ1JywgJ0tydDE0JywgJ0RjbicsICdDb2wxYTEnLCdDb2w4YTEnKQojZ2VuZXNfdG9fY2hlY2sgPSBjKCdBbGInLCAnQ3lwMmYyJywgJ0N5cDJlMScsICdIYW1wJykKCkZlYXR1cmVQbG90KHRpc3MsIGdlbmVzX3RvX2NoZWNrLCBwdC5zaXplID0gMSwgbkNvbCA9IDMpCmBgYAoKRG90cGxvdHMgbGV0IHlvdSBzZWUgdGhlIGludGVuc2l0eSBvZiBleHBwcmVzc2lvbiBhbmQgdGhlIGZyYWN0aW9uIG9mIGNlbGxzIGV4cHJlc3NpbmcgZm9yIGVhY2ggb2YgeW91ciBnZW5lcyBvZiBpbnRlcmVzdC4KYGBge3J9ClZsblBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2spCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTh9CiMgVG8gY2hhbmdlIHRoZSB5LWF4aXMgdG8gc2hvdyByYXcgY291bnRzLCBhZGQgdXNlLnJhdyA9IFQuCkRvdFBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2ssIHBsb3QubGVnZW5kID0gVCkKYGBgCmBgYHtyfQpCdWlsZENsdXN0ZXJUcmVlKHRpc3MpCgpgYGAKCgoKCgpIb3cgYmlnIGFyZSB0aGUgY2x1c3RlcnM/CmBgYHtyfQp0YWJsZSh0aXNzQGlkZW50KQpgYGAKCgoKV2hpY2ggbWFya2VycyBpZGVudGlmeSBhIHNwZWNpZmljIGNsdXN0ZXI/CgpgYGB7cn0KY2x1c3QubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSB0aXNzLCBpZGVudC4xID0gMCwgb25seS5wb3MgPSBUUlVFLCBtaW4ucGN0ID0gMC4yNSwgdGhyZXNoLnVzZSA9IDAuMjUpCkRvdFBsb3QodGlzcywgZ2VuZXMucGxvdCA9IHJvd25hbWVzKGNsdXN0Lm1hcmtlcnMpWzE6MjBdLCBwbG90LmxlZ2VuZCA9IFQpCmBgYAoKCmBgYHtyfQpwcmludCh4ID0gaGVhZCh4PSBjbHVzdC5tYXJrZXJzLCBuID0gMTApKQpgYGAKCllvdSBjYW4gYWxzbyBjb21wdXRlIGFsbCBtYXJrZXJzIGZvciBhbGwgY2x1c3RlcnMgYXQgb25jZS4gVGhpcyBtYXkgdGFrZSBzb21lIHRpbWUuCgpgYGB7cn0KdGlzcy5tYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKG9iamVjdCA9IHRpc3MsIG9ubHkucG9zID0gVFJVRSwgbWluLnBjdCA9IDAuMjUsIHRocmVzaC51c2UgPSAwLjI1KQpgYGAKCkRpc3BsYXkgdGhlIHRvcCBtYXJrZXJzIHlvdSBjb21wdXRlZCBhYm92ZS4KYGBge3J9CiN0aXNzLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3Bfbig1LCBhdmdfZGlmZikKdGlzcy5tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24oMTAsIGF2Z19kaWZmKQpgYGAKCiMjIEFzc2lnbmluZyBjZWxsIHR5cGUgaWRlbnRpdHkgdG8gY2x1c3RlcnMKCkF0IGEgY29hcnNlIGxldmVsLCB3ZSBjYW4gdXNlIGNhbm9uaWNhbCBtYXJrZXJzIHRvIG1hdGNoIHRoZSB1bmJpYXNlZCBjbHVzdGVyaW5nIHRvIGtub3duIGNlbGwgdHlwZXM6CgowOiBhbHBoYQoxOiBiZXRhCjI6IGJldGEKMzogZXhvY3JpbmUKNDogZHVjdAo1OiBkZWx0YQo2OiBnYW1tYQo3OiBlbmRvdGhlbGlhbAo4OiBpbW11bmUKOTogc3RlbGxhdGUKCmBgYHtyfQojIHN0YXNoIGN1cnJlbnQgY2x1c3RlciBJRHMKdGlzcyA8LSBTdGFzaElkZW50KG9iamVjdCA9IHRpc3MsIHNhdmUubmFtZSA9ICJjbHVzdGVyLmlkcyIpCgojIGVudW1lcmF0ZSBjdXJyZW50IGNsdXN0ZXIgSURzIGFuZCB0aGUgbGFiZWxzIGZvciB0aGVtCmNsdXN0ZXIuaWRzIDwtIGMoMCwgMSwgMiwgMywgNCwgNSwgNiwgNykKYW5ub3RhdGlvbiA8LSBjKCJibGFkZGVyIGNlbGwiLCAiYmxhZGRlciBjZWxsIiwgIm1lc2VuY2h5bWFsIGNlbGwiLCAibWVzZW5jaHltYWwgY2VsbCIsICJtZXNlbmNoeW1hbCBjZWxsIiwgIm1lc2VuY2h5bWFsIGNlbGwiLCAiYmFzYWwgY2VsbCBvZiB1cm90aGVsaXVtIiwgImJsYWRkZXIgY2VsbCIpCmNlbGxfb250b2xvZ3lfaWQgPSBjKCJDTDoxMDAxMzE5IiwgIkNMOjEwMDEzMTkiLCAiQ0w6MDAwODAxOSIsICJDTDowMDA4MDE5IiwgIkNMOjAwMDgwMTkiLCAiQ0w6MDAwODAxOSIsICJDTDoxMDAwNDg2IiwgIkNMOjEwMDEzMTkiKQoKdGlzc0BtZXRhLmRhdGFbLCdhbm5vdGF0aW9uJ10gPC0gcGx5cjo6bWFwdmFsdWVzKHggPSB0aXNzQG1ldGEuZGF0YSRjbHVzdGVyLmlkcywgZnJvbSA9IGNsdXN0ZXIuaWRzLCB0byA9IGFubm90YXRpb24pCnRpc3NAbWV0YS5kYXRhWywnY2VsbF9vbnRvbG9neV9pZCddIDwtIHBseXI6Om1hcHZhbHVlcyh4ID0gdGlzc0BtZXRhLmRhdGEkY2x1c3Rlci5pZHMsIGZyb20gPSBjbHVzdGVyLmlkcywgdG8gPSBjZWxsX29udG9sb2d5X2lkKQoKVFNORVBsb3Qob2JqZWN0ID0gdGlzcywgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMC41LCBncm91cC5ieT0nYW5ub3RhdGlvbicpCmBgYAoKYGBge3J9ClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLnJldHVybiA9IFRSVUUsIGdyb3VwLmJ5ID0gIm1vdXNlLnNleCIpCgpgYGAKCgojIyBDaGVja2luZyBmb3IgYmF0Y2ggZWZmZWN0cwoKCkNvbG9yIGJ5IG1ldGFkYXRhLCBsaWtlIHBsYXRlIGJhcmNvZGUsIHRvIGNoZWNrIGZvciBiYXRjaCBlZmZlY3RzLgpgYGB7cn0KVFNORVBsb3Qob2JqZWN0ID0gdGlzcywgZG8ucmV0dXJuID0gVFJVRSwgZ3JvdXAuYnkgPSAicGxhdGUuYmFyY29kZSIpCmBgYAoKUHJpbnQgYSB0YWJsZSBzaG93aW5nIHRoZSBjb3VudCBvZiBjZWxscyBpbiBlYWNoIGlkZW50aXR5IGNhdGVnb3J5IGZyb20gZWFjaCBwbGF0ZS4KCmBgYHtyfQp0YWJsZShhcy5jaGFyYWN0ZXIodGlzc0BpZGVudCksIGFzLmNoYXJhY3Rlcih0aXNzQG1ldGEuZGF0YSRwbGF0ZS5iYXJjb2RlKSkKYGBgCgpgYGB7cn0KIyBHZXQgbWFya2VycyBmb3IgYSBwYXJ0aWN1bGFyIGNsdXN0ZXIKZm9yIChpIGluIDA6Nykge2NsdXN0ZXJtYXJrZXJzID0gZmlsdGVyKHRpc3MubWFya2VycywgY2x1c3RlciA9PSBpKSRnZW5lCkRvdFBsb3QodGlzcywgZ2VuZXMucGxvdCA9IGNsdXN0ZXJtYXJrZXJzWzE6MjBdLCBwbG90LmxlZ2VuZCA9IFQpfQpgYGAKCgpgYGB7cn0KCiMgR2V0IHN1YnRpc3N1ZSwgZWcsIHRoZSBlbmRvY3JpbmUgY2x1c3RlcnMKc3VidGlzcyA8LSBTdWJzZXREYXRhKG9iamVjdCA9IHRpc3MsIGlkZW50LnVzZSA9IGMoMiksCiAgZG8uY2VudGVyID0gRiwgZG8uc2NhbGUgPSBGKQoKYGBgCgpgYGB7cn0Kc3VidGlzcyA8LSBTdWJzZXREYXRhKG9iamVjdCA9IHRpc3MsIGlkZW50LnVzZSA9IGMoMiksIGRvLmNlbnRlciA9IEYsIGRvLnNjYWxlID0gRiwgY2VsbHMudXNlID0gKQoKYGBgCgpgYGB7cn0Kc3VidGlzcyA8LSBOb3JtYWxpemVEYXRhKG9iamVjdCA9IHN1YnRpc3MpCnN1YnRpc3MgPC0gU2NhbGVEYXRhKG9iamVjdCA9IHN1YnRpc3MsIHZhcnMudG8ucmVncmVzcyA9IGMoIm5SZWFkcyIsICJwZXJjZW50LnJpYm8iLCJSbjQ1cyIpKQpgYGAKCmBgYHtyfQpzdWJ0aXNzIDwtIEZpbmRWYXJpYWJsZUdlbmVzKG9iamVjdCA9IHN1YnRpc3MsIGRvLnBsb3QgPSBUUlVFLCB4LmhpZ2guY3V0b2ZmID0gSW5mLCB5LmN1dG9mZiA9IDAuOCkKc3VidGlzcyA8LSBSdW5QQ0Eob2JqZWN0ID0gc3VidGlzcywgcGNzLmNvbXB1dGUgPSAyMCwgd2VpZ2h0LmJ5LnZhciA9IEYpCnN1YnRpc3MgPC0gUHJvamVjdFBDQShvYmplY3QgPSBzdWJ0aXNzLCBkby5wcmludCA9IEZBTFNFKQpgYGAKCmBgYHtyfQojIElmIHRoaXMgZmFpbHMgZm9yIHlvdXIgc3Vic2V0LCBpdCBtYXkgYmUgdGhhdCBjZWxscy51c2UgaXMgbW9yZSBjZWxscyB0aGFuIHlvdSBoYXZlIGxlZnQhIFRyeSByZWR1Y2luZyBpdC4KUENIZWF0bWFwKG9iamVjdCA9IHN1YnRpc3MsIHBjLnVzZSA9IDE6MywgY2VsbHMudXNlID0gMjUwLCBkby5iYWxhbmNlZCA9IFRSVUUsIGxhYmVsLmNvbHVtbnMgPSBGQUxTRSwgbnVtLmdlbmVzID0gMTIpCmBgYAoKYGBge3J9ClBDRWxib3dQbG90KG9iamVjdCA9IHN1YnRpc3MpCmBgYAoKYGBge3J9CiMgU2V0IG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cy4gCnN1Yi5uLnBjcyA9IDUKYGBgCgpgYGB7cn0KIyBTZXQgcmVzb2x1dGlvbiAKc3ViLnJlcy51c2VkIDwtIDEKCnN1YnRpc3MgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IHN1YnRpc3MsIHJlZHVjdGlvbi50eXBlID0gInBjYSIsIGRpbXMudXNlID0gMTpzdWIubi5wY3MsIAogICAgcmVzb2x1dGlvbiA9IHN1Yi5yZXMudXNlZCwgLHByaW50Lm91dHB1dCA9IDAsIHNhdmUuU05OID0gVFJVRSkKYGBgCgpgYGB7cn0KIyBJZiBjZWxscyBhcmUgdG9vIHNwcmVhZCBvdXQsIHlvdSBjYW4gcmFpc2UgdGhlIHBlcnBsZXhpdHkuIElmIHlvdSBoYXZlIGZldyBjZWxscywgdHJ5IGEgbG93ZXIgcGVycGxleGl0eSAoYnV0IG5ldmVyIGxlc3MgdGhhbiAxMCkuCnN1YnRpc3MgPC0gUnVuVFNORShvYmplY3QgPSBzdWJ0aXNzLCBkaW1zLnVzZSA9IDE6c3ViLm4ucGNzLCBzZWVkLnVzZSA9IDEwLCBwZXJwbGV4aXR5PTIwKQpgYGAKCmBgYHtyfQojIG5vdGUgdGhhdCB5b3UgY2FuIHNldCBkby5sYWJlbD1UIHRvIGhlbHAgbGFiZWwgaW5kaXZpZHVhbCBjbHVzdGVycwpUU05FUGxvdChvYmplY3QgPSBzdWJ0aXNzLCBkby5sYWJlbCA9IFQpCmBgYApgYGB7cn0KVFNORVBsb3Qob2JqZWN0ID0gc3VidGlzcywgZG8ucmV0dXJuID0gVFJVRSwgZ3JvdXAuYnkgPSAibW91c2Uuc2V4IikKYGBgCgpgYGB7cn0KZ2VuZXNfdG9fY2hlY2sgPSBjKCdIaGlwJywnRGNuJywgJ0dsaTEnLCdHbGkyJywgJ1NtbycsJ0NvbDFhMScsJ0NvbDhhMScpCiNnZW5lc190b19jaGVjayA9IGMoJ0FsYicsICdDeXAyZjInLCAnQ3lwMmUxJywgJ0hhbXAnKQoKRmVhdHVyZVBsb3Qoc3VidGlzcywgZ2VuZXNfdG9fY2hlY2ssIHB0LnNpemUgPSAxLCBuQ29sID0gMykKYGBgCgpgYGB7cn0KVmxuUGxvdChzdWJ0aXNzLCBnZW5lc190b19jaGVjaykKYGBgCgpgYGB7cn0KY2x1c3QubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSBzdWJ0aXNzLCBpZGVudC4xID0gMCwgb25seS5wb3MgPSBUUlVFLCBtaW4ucGN0ID0gMC4yNSwgdGhyZXNoLnVzZSA9IDAuMjUpCmNsdXN0Lm1hcmtlcnMgCmBgYAoKYGBge3J9CmNsdXN0Lm1hcmtlcnN1cm8gPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gc3VidGlzcywgaWRlbnQuMSA9IDAsIG9ubHkucG9zID0gVFJVRSwgbWluLnBjdCA9IDAuMjUsIHRocmVzaC51c2UgPSAwLjI1KQpjbHVzdC5tYXJrZXJzdXJvCmBgYAoKCmBgYHtyfQpHZW5lUGxvdChzdWJ0aXNzLCAnVXBrM2EnLCAnS3J0MTQnLCB1c2UucmF3ID0gVCkKYGBgCgpgYGB7cn0KQnVpbGRDbHVzdGVyVHJlZShzdWJ0aXNzKQpgYGAKCmBgYHtyfQpWbG5QbG90KHN1YnRpc3MsIGdlbmVzX3RvX2NoZWNrKQpgYGAKCkxhdGVyIG9uIChpbiBGaW5kQ2x1c3RlcnMgYW5kIFRTTkUpIHlvdSB3aWxsIHBpY2sgYSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGtlZXBpbmcgdGhlIG1ham9yIGRpcmVjdGlvbnMgb2YgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGFuZCwgaWRlYWxseSwgc3VwcmVzc2luZyBub2lzZS4gVGhlcmUgaXMgbm8gY29ycmVjdCBhbnN3ZXIgdG8gdGhlIG51bWJlciB0byB1c2UsIGJ1dCBhIGRlY2VudCBydWxlIG9mIHRodW1iIGlzIHRvIGdvIHVudGlsIHRoZSBwbG90IHBsYXRlYXVzLgoKQ2hlY2sgZXhwcmVzc2lvbiBvZiBnZW5lcyBvZiBpbnRlcnNldC4KCmBgYHtyfQpnZW5lc190b19jaGVjayA9IGMoJ0J0ZzInLCdTZ2sxJywnSnVuJywnU3JzZjInKQoKRmVhdHVyZVBsb3Qoc3VidGlzcywgZ2VuZXNfdG9fY2hlY2ssIHB0LnNpemUgPSAxKQpgYGAKCkRvdHBsb3RzIGxldCB5b3Ugc2VlIHRoZSBpbnRlbnNpdHkgb2YgZXhwcHJlc3Npb24gYW5kIHRoZSBmcmFjdGlvbiBvZiBjZWxscyBleHByZXNzaW5nIGZvciBlYWNoIG9mIHlvdXIgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7cn0KIyBUbyBjaGFuZ2UgdGhlIHktYXhpcyB0byBzaG93IHJhdyBjb3VudHMsIGFkZCB1c2UucmF3ID0gVC4KRG90UGxvdChzdWJ0aXNzLCBnZW5lc190b19jaGVjaywgcGxvdC5sZWdlbmQgPSBUKQpgYGAKCkhvdyBiaWcgYXJlIHRoZSBjbHVzdGVycz8KYGBge3J9CnRhYmxlKHN1YnRpc3NAaWRlbnQpCmBgYAoKIyMgQ2hlY2tpbmcgZm9yIGJhdGNoIGVmZmVjdHMKCkNvbG9yIGJ5IG1ldGFkYXRhLCBsaWtlIHBsYXRlIGJhcmNvZGUsIHRvIGNoZWNrIGZvciBiYXRjaCBlZmZlY3RzLgpgYGB7cn0KVFNORVBsb3Qob2JqZWN0ID0gc3VidGlzcywgZG8ucmV0dXJuID0gVFJVRSwgZ3JvdXAuYnkgPSAicGxhdGUuYmFyY29kZSIpCmBgYAoKUHJpbnQgYSB0YWJsZSBzaG93aW5nIHRoZSBjb3VudCBvZiBjZWxscyBpbiBlYWNoIGlkZW50aXR5IGNhdGVnb3J5IGZyb20gZWFjaCBwbGF0ZS4KCmBgYHtyfQp0YWJsZShhcy5jaGFyYWN0ZXIoc3VidGlzc0BpZGVudCksIGFzLmNoYXJhY3RlcihzdWJ0aXNzQG1ldGEuZGF0YSRwbGF0ZS5iYXJjb2RlKSkKYGBgCgoKIyBTYXZlIHRoZSBSb2JqZWN0IGZvciBsYXRlcgpXaGVuIHlvdSBzYXZlIHRoZSBhbm5vdGF0ZWQgdGlzc3VlLCBwbGVhc2UgZ2l2ZSBpdCBhIG5hbWUuCgpgYGB7cn0KZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICd0aXNzdWVfc2V1cmF0X3JvYmonLCAKCQkgIHBhc3RlMCh0aXNzdWVfb2ZfaW50ZXJlc3QsICJfc2V1cmF0X3Rpc3MuUm9iaiIpKQpwcmludChmaWxlbmFtZSkKc2F2ZSh0aXNzLCBmaWxlPWZpbGVuYW1lKQpgYGAKCmBgYHtyfQojIFRvIHJlbG9hZCBhIHNhdmVkIG9iamVjdAojIGZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAndGlzc3VlX3NldXJhdF9yb2JqJywgCiMgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKHRpc3N1ZV9vZl9pbnRlcmVzdCwgIl9zZXVyYXRfdGlzcy5Sb2JqIikpCiMgbG9hZChmaWxlPWZpbGVuYW1lKQpgYGAKCgoKIyBFeHBvcnQgdGhlIGZpbmFsIG1ldGFkYXRhCgpTbyB0aGF0IEJpb2h1YiBjYW4gZWFzaWx5IGNvbWJpbmUgYWxsIHlvdXIgYW5ub3RhdGlvbnMsIHBsZWFzZSBleHBvcnQgdGhlbSBhcyBhIHNpbXBsZSBjc3YuCgpgYGB7cn0KaGVhZCh0aXNzQG1ldGEuZGF0YSkKYGBgCgoKYGBge3J9CmZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAndGlzc3VlX2Fubm90YXRpb25fY3N2JywgCgkJICBwYXN0ZTAodGlzc3VlX29mX2ludGVyZXN0LCAiX2Fubm90YXRpb24uY3N2IikpCndyaXRlLmNzdih0aXNzQG1ldGEuZGF0YVssYygncGxhdGUuYmFyY29kZScsJ2Fubm90YXRpb24nLCdjZWxsX29udG9sb2d5X2lkJyldLCBmaWxlPWZpbGVuYW1lKQpgYGA=